class Vue extends EventTarget{
    constructor(opts){
        super();
        this.$options = opts;
        this.observe(opts.data);
        this._data = opts.data;
        this.compile();
    }
    // 观察数据
    observe(data){
        let keys = Object.keys(data);
        let _this = this;
        keys.forEach(key=>{
            let value = data[key];
            Object.defineProperty(data,key,{
                configurable:true,
                enumerable:true,
                get(){
                    console.log("get");
                    return value;
                },
                set(newValue){
                    // 修改之后做响应；
                    console.log("set",newValue);
                    // 触发compile编译；
                    _this.dispatchEvent(new CustomEvent(key,{
                        detail:newValue
                    }))
                    value = newValue;
                }
            })
        })
    }

    compile(){
        let el = document.querySelector(this.$options.el);
        this.compileNodes(el);
    }
    compileNodes(el){
        let childNodes = el.childNodes;
        // console.log(childNodes);
        childNodes.forEach(node=>{
            if(node.nodeType===1){
                // 元素节点
                if(node.childNodes.length>0){
                    this.compileNodes(node);
                }
            }else if(node.nodeType === 3){
                // 文本
                let textContent = node.textContent;
                // console.log(textContent);
                let reg = /\{\{\s*([^\{\}\s]+)\s*\}\}/g;
                if(reg.test(textContent)){
                    let $1 = RegExp.$1;
                    // console.log("有大胡子语法","("+$1+")");
                    // console.log(this._data[$1]);
                    node.textContent = node.textContent.replace(reg,this._data[$1]);
                    this.addEventListener($1,(e)=>{
                        console.log("触发了set操作，需要视图更新",e);
                        let newValue = e.detail;
                        let oldValue  = this._data[$1];
                        node.textContent = node.textContent.replace(oldValue,newValue)
                    })
                }
            }
        })
    }
}